package com.groupseven.backend.controller;


import com.groupseven.backend.configuration.WebLog.WebLog;
import com.groupseven.backend.domain.ResultType;
import com.groupseven.backend.domain.User.User;
import com.groupseven.backend.domain.User.UserRole;
import com.groupseven.backend.services.UserService;
import com.groupseven.backend.test.DataEncode;
import com.groupseven.backend.util.Jwt.JwtToken;
import com.groupseven.backend.util.Jwt.JwtUtil;
import com.groupseven.backend.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


@Slf4j
@RestController
@RequestMapping(value = "/api/v1/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private DataEncode dataEncode;
    @Autowired
    private RedisUtil redis;


    /**
     * 用户登录
     * @Author 王志华
     * @param user
     * @return
     */
    @WebLog(operateType = "用户登录")
    @PostMapping(value = "/login")
    public ResultType login(@RequestBody @Valid User user) {
//        byte[] name = Base64.decodeBase64(user.getUsername().getBytes());
//        byte[] pw = Base64.decodeBase64(user.getPassword().getBytes());
//        user.setUsername(new String(name));
//        user.setPassword(new String(pw));
        System.out.println(user.getUsername());
        String Username =user.getUsername();
        Date now = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        String date = dateFormat.format(now);
        if (user.getUsername()==null||user.getPassword()==null){
            return new ResultType(0,"账号或密码为空！",200);
        }
        user.setUsername(dataEncode.encodeBae64(user.getUsername()));
        user.setPassword(dataEncode.encodeBae64(user.getPassword()));
//        if(redis.hasKey(user.getUsername())){
//            String str1 = redis.get(user.getUsername()).toString();
//        }
//        if(userService.selectByUsernameAndPassword(user)!=null){
//            User tmp = userService.selectByUsernameAndPassword(user);
//            if(tmp.getIsCurrentOnline() == 1){
//                return new ResultType(0,"不可重复登陆！",200);
//            }
//        }
        //生成token字符串
        String token = JwtUtil.getJwtToken(user.getUsername(), user.getPassword(),"groupseven");   //toHex转换成16进制，32为字符
        JwtToken jwtToken = new JwtToken(token);
        System.out.println(jwtToken);
        System.out.println(token);
        Subject subject = SecurityUtils.getSubject();
        ResultType res = new ResultType();
        try {
            System.out.println(token);
            if(redis.hasKey(Username+"在登录")){
                redis.del(Username+"在登录");
                redis.set(Username+"在登录","1");
            } else {
                redis.set(Username+"在登录","1");
            }
            subject.login(jwtToken);
            res.setCode(1);
            res.setMsg("登陆成功");
            res.setStatus(200);
            User u1 = userService.selectByUsername(user.getUsername());
            res.setUser(u1);
            res.setToken(token);
//            userService.updateLastLoginDate(date,user.getUsername());
        } catch (UnknownAccountException e){
            res.setCode(0);
            res.setMsg("无效用户，用户不存在");
            res.setStatus(604);
//            e.printStackTrace();
        } catch (IncorrectCredentialsException e){
            res.setCode(0);
            res.setMsg("密码输入错误");
            res.setStatus(603);
//            e.printStackTrace();
        } catch (ExpiredCredentialsException e){
            res.setCode(0);
            res.setMsg("token过期，请重新登录");
            res.setStatus(602);
//            e.printStackTrace();
        } finally {
            return res;
        }
//        String pw = dataEncode.encodeBae64(user.getPassword().replaceAll("\\\\","").trim());
//        String Username = dataEncode.encodeBae64(user.getUsername().replaceAll("\\\\","").trim());
//        System.out.println(Username+pw);
//        User u1 = new User(null,pw,Username);
//        User u2 = userService.selectByUsername(Username);
//        System.out.println(u2.getUsername()+"用户类型为："+u2.getUsertype());
//        if(userService.selectById(u2)==null){
//            return new ResultType(0,"用户不存在！",200,null,null,null,null,null);
//        }
//        if(pw.equals(userService.selectById(u2).getPassword())&&Username.equals(userService.selectByUsername(Username).getUsername())){
//            return new ResultType(1,"登陆成功！",200,null,u2,null,null,null,null);
//        }
//        return new ResultType(0,"账号或密码错误！",200,null,null,null,null,null);
    }

    /**
     * 用户登出
     * @Author 王志华
     * @param user
     * @return
     */
    @PostMapping("/logout")
    public ResultType logout(@RequestBody User user){
        redis.del(user.getUsername()+"的token");
        if (userService.logout(dataEncode.encodeBae64(user.getUsername())) == 1){
            return new ResultType(1,"登出成功！",200);
        }
        return new ResultType(0,"登出失败！",200);
    }

    /**
     * 查询所有用户------管理员功能
     * @Author 王志华
     * @return
     */
    @WebLog(operateType = "查询所有用户")
    @GetMapping("/")
    public ResultType getAllUsers(){
        List<User> tmp = userService.getAllUsers();

        for (User user : tmp){
            user.setUserid(dataEncode.decodeBae64(user.getUserid()));
            user.setPassword(dataEncode.decodeBae64(user.getPassword()));
            user.setUsername(dataEncode.decodeBae64(user.getUsername()));
        }
        return new ResultType(1,"查询成功",200,null,tmp,null,null,null);
    }


    @PutMapping("/role")
    public ResultType updateRole(@RequestBody @Valid UserRole ur){
        System.out.println("更新角色中："+ur.getUsername()+ur.getUsertype());
        ur.setUsername(dataEncode.encodeBae64(ur.getUsername()));
        if(userService.updateUserRole(ur)==1){
            return new ResultType(1,"更新成功！",200);
        }
        return new ResultType(0,"更新失败！",200);
    }

    /**
     * 增添用户------管理员功能
     * @Author 王志华
     * @param user
     * @return
     */
    @PutMapping("/")
    public ResultType addUser(@RequestBody @Valid User user){
        user.setUsername(dataEncode.encodeBae64(user.getUsername()));
        System.out.println("用户名："+user.getUsername());
        user.setPassword(dataEncode.encodeBae64(user.getPassword()));
        System.out.println("密码："+user.getPassword());
        user.setUserid(user.getUsername());
        System.out.println("用户id："+user.getUserid());
        if (userService.addUser(user)==1){
            return new ResultType(1,"添加用户成功！",200);
        }
        return new ResultType(0,"添加用户失败！",200);
    }

    /**
     * 删除用户------管理员功能
     * @Author 王志华
     * @param Usernum
     * @return
     */
    @DeleteMapping("/{Usernum}")
    public ResultType deleteUser(@PathVariable @Valid int Usernum){
        if (userService.deleteByUsername(Usernum)==1){
            return new ResultType(1,"删除成功！",200);
        }
        return new ResultType(0,"删除失败！",200);
    }

    @PostMapping("/s/")
    public ResultType multi_delete(@RequestBody List<User> users){
        if(userService.multi_delete(users)){
            return new ResultType(1,"批量删除成功！",200);
        }
        return new ResultType(0,"批量删除失败！",200);
    }

    @GetMapping("/search/{query}")
    public ResultType FuzzySearch(@PathVariable String query){
        List<User> users = userService.FuzzySearch(query);
        ResultType result = new ResultType();
        if(users!=null&&users.size()!=0){
            result.setCode(1);
            result.setMsg("查询成功！");
            result.setStatus(200);
            result.setUsers(users);
            return result;
        }
        return new ResultType(0,"查询失败！",200);
    }

}
